package com.jinyi.wwdeng.autodialer.repository

import android.content.Context
import android.util.Log
import com.jinyi.wwdeng.autodialer.MyApplication
import com.jinyi.wwdeng.autodialer.data.CallDatabase
import com.jinyi.wwdeng.autodialer.data.CallTask
import com.jinyi.wwdeng.autodialer.data.CallTaskEntity
import com.jinyi.wwdeng.autodialer.data.CallTaskDao
import com.jinyi.wwdeng.autodialer.data.toCallTaskEntity
import com.jinyi.wwdeng.autodialer.http.HttpApi
import com.jinyi.wwdeng.autodialer.http.HttpUtil
import com.jinyi.wwdeng.autodialer.utils.AppConfig
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject

/**
 * 数据仓库
 */
class CallRepository private constructor(context: Context){
    private val phoneNumberDao: CallTaskDao = CallDatabase.getInstance(context).callDao()
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    companion object {
        @Volatile
        private var INSTANCE: CallRepository? = null

        fun getInstance(context: Context): CallRepository {
            return INSTANCE ?: synchronized(this) {
                val instance = CallRepository(context.applicationContext)
                INSTANCE = instance
                instance
            }
        }
    }

    // 从API获取号码列表（挂起函数）
    suspend fun fetchPhoneNumbersFromApi(): JSONObject? = withContext(Dispatchers.IO) {
        return@withContext try {
            val body = JSONObject().apply {
                put("sysLoginName", AppConfig.userName)
                put("token",AppConfig.userToken)
            }
            val data  = HttpUtil.getInstance().postJsonSuspend(MyApplication.instance, HttpApi.API_GET_NUMBER,body.toString(),null)
            val code = data.optInt("code")
            when(code){
                0 -> {

                    data.optJSONObject("obj")
                }
                else -> {
                    null
                }
            }
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "request error: ${e.message}")
            null
        }
    }

    // 批量插入号码到数据库（挂起函数）
    suspend fun insertPhoneNumbers(phoneNumbers: List<String>): Int = withContext(Dispatchers.IO) {
        return@withContext try {
            val existingNumbers = getExistingPhoneNumbers()
            val existingNumberSet = existingNumbers.toSet()

            val newNumbers = phoneNumbers
                .filter { !existingNumberSet.contains(it) }
                .map { CallTask(phoneNumber = it) }

            if (newNumbers.isNotEmpty()) {
                newNumbers.forEach { phoneNumberDao.insert(it.toCallTaskEntity()) }
                newNumbers.size
            } else {
                0
            }
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "insert phone numbers error: ${e.message}")
            0
        }
    }

    // 单个插入号码到数据库（挂起函数）
    suspend fun insertPhoneNumber(item: CallTaskEntity): Int = withContext(Dispatchers.IO) {
        return@withContext try {
            val number = item.phoneNumber
            if (number.isNotEmpty()){
                val existingNumbers = getExistingPhoneNumbers()
                val existingNumberSet = existingNumbers.toSet()

                if (!existingNumberSet.contains(number)){
                    phoneNumberDao.insert(item)
                    1
                } else {
                    0
                }
            } else {
                0
            }
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "insert phone number error: ${e.message}")
            0
        }
    }

    // 获取所有已存在的号码（挂起函数）
    suspend fun getExistingPhoneNumbers(): List<String> = withContext(Dispatchers.IO) {
        return@withContext try {
            //获取所有号码
            phoneNumberDao.getAllTasks()
                .map { it.phoneNumber }
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "get all phone numbers error: ${e.message}")
            emptyList()
        }
    }

    // 获取待拨打的号码列表（挂起函数）
    suspend fun getPendingNumbers(limit: Int = 1): List<CallTaskEntity> = withContext(Dispatchers.IO) {
        return@withContext try {
            //获取待拨号的所有号码
            phoneNumberDao.getPendingTasks(limit)
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "get pending phone number error: ${e.message}")
            emptyList()
        }
    }

    // 获取待拨打的号码单个（挂起函数）
    suspend fun getPendingNumber(maxRetry: Int = 3): CallTaskEntity? = withContext(Dispatchers.IO) {
        return@withContext try {
            //获取待拨号的所有号码
            val pendingNumbers = getPendingNumbers(maxRetry)
            if (pendingNumbers.isNotEmpty()){
                pendingNumbers[0]
            } else {
                null
            }
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "get pending phone number error: ${e.message}")
            null
        }
    }

    // 获取待拨打号码数量（挂起函数）
    suspend fun getPendingCount(): Int = withContext(Dispatchers.IO) {
        return@withContext try {
            phoneNumberDao.getPendingCount()
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "get pending count error: ${e.message}")
            0
        }
    }

    // 更新号码状态（挂起函数）
    suspend fun updatePhoneNumber(phoneNumber: CallTaskEntity) = withContext(Dispatchers.IO) {
        try {
            phoneNumberDao.update(phoneNumber.copy())
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "update phone number error: ${e.message}")
        }
    }

    // 清除所有号码数据（挂起函数）
    private suspend fun clearAllNumbers() = withContext(Dispatchers.IO) {
        try {
            phoneNumberDao.deleteAll()
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "clear phone number error: ${e.message}")
        }
    }

    // 获取所有号码（挂起函数）
    suspend fun getAllNumbers(): List<CallTaskEntity> = withContext(Dispatchers.IO) {
        return@withContext try {
            phoneNumberDao.getAllTasks()
        } catch (e: Exception) {
            Log.e("PhoneNumberRepository", "get all phone number error: ${e.message}")
            emptyList()
        }
    }

    // 保持原有的回调方法（兼容旧代码）
    fun fetchPhoneNumbersFromApi(callback: (JSONObject?) -> Unit) {
        scope.launch {
            val result = fetchPhoneNumbersFromApi()
            withContext(Dispatchers.Main) {
                callback(result)
            }
        }
    }

    /**
     * 批量插入号码
     */
    fun insertPhoneNumbers(phoneNumbers: List<String>, callback: (Int) -> Unit) {
        scope.launch {
            val result = insertPhoneNumbers(phoneNumbers)
            withContext(Dispatchers.Main) {
                callback(result)
            }
        }
    }

    fun getExistingPhoneNumbers(callback: (List<String>) -> Unit) {
        scope.launch {
            val result = getExistingPhoneNumbers()
            withContext(Dispatchers.Main) {
                callback(result)
            }
        }
    }

    fun getPendingNumbers(maxRetry: Int = 3, callback: (List<CallTaskEntity>) -> Unit) {
        scope.launch {
            val result = getPendingNumbers(maxRetry)
            withContext(Dispatchers.Main) {
                callback(result)
            }
        }
    }

    fun getPendingCount(callback: (Int) -> Unit) {
        scope.launch {
            val result = getPendingCount()
            withContext(Dispatchers.Main) {
                callback(result)
            }
        }
    }

    fun updatePhoneNumber(phoneNumber: CallTaskEntity, callback: (() -> Unit)? = null) {
        scope.launch {
            updatePhoneNumber(phoneNumber)
            withContext(Dispatchers.Main) {
                callback?.invoke()
            }
        }
    }

    fun clearAllNumbers(callback: (() -> Unit)? = null) {
        scope.launch {
            clearAllNumbers()
            withContext(Dispatchers.Main) {
                callback?.invoke()
            }
        }
    }

    fun getAllNumbers(callback: (List<CallTaskEntity>) -> Unit) {
        scope.launch {
            val result = getAllNumbers()
            withContext(Dispatchers.Main) {
                callback(result)
            }
        }
    }

    // 关闭协程作用域
    fun shutdown() {
        scope.cancel()
    }
}